public class Player {
	public Map m;
	public Unit[] unit;
	public Structure[] structure;
	public Explorer[] explorer;
	public Colonist[] colonist;
	public Melee[] melee;
	public Range[] range;
	public Base[] base;
	public Farm[] farm;
	public Rally[] rally;
	public Unit[] allArmy;
	public Unit[] combatArmy;
	public Unit[] supportArmy;
	private Tileable[][][] tileables;
	public int explorerSize;
	public int colonistSize;
	public int meleeSize;
	public int rangeSize;
	public int baseSize;
	public int farmSize;
	public int structureSize;
	public int unitSize;
	public int rallySize;
	public int allArmySize;
	public int combatArmySize;
	public int supportArmySize;
	public int gold;
	public int lumber;
	public int food;
	public int playerID;
	public int clockstep;
	public IDTable unitID;
	public IDTable structureID;
	public IDTable rallyID;
	public int startupX;
	public int startupY;
	public int[][] arrayOfSizes;

	private final int maxID = 25;

	public Player(int _playerID, int _x, int _y, Map m) {
		this.m=m;
		this.playerID = _playerID;
		this.startupX = _x;
		this.startupY = _y;
		this.gold = 100;
		this.lumber = 100;
		this.food = 10000;
		this.clockstep = 0;
		this.unit = new Unit[25];
		this.structure = new Structure[10];
		this.explorer = new Explorer[10];
		this.colonist = new Colonist[10];
		this.melee = new Melee[10];
		this.range = new Range[10];
		this.structure = new Structure[10];
		this.base = new Base[10];
		this.farm = new Farm[10];
		this.rally = new Rally[10];
		
		this.allArmy = new Unit[10];
		this.combatArmy = new Unit[10];
		this.supportArmy = new Unit[10];
		
		this.explorerSize = 0;
		this.colonistSize = 0;
		this.meleeSize = 0;
		this.rangeSize = 0;
		this.baseSize = 0;
		this.farmSize = 0;
		this.unitSize = 0;
		this.structureSize = 0;
		this.rallySize = 0;
		this.allArmySize = 0;
		this.combatArmySize = 0;
		this.supportArmySize = 0;
		this.unitID = new IDTable(maxID);
		this.structureID = new IDTable(maxID);
		this.rallyID = new IDTable(maxID);
		this.arrayOfSizes = new int[4][4];
		tileables = new Tileable[4][][];
		tileables[0] = new Tileable[4][];
		tileables[1] = new Tileable[2][];
		tileables[2] = new Tileable[1][];
		tileables[3] = new Tileable[3][];
		tileables[0][0] = explorer;
		tileables[0][1] = colonist;
		tileables[0][2] = melee;
		tileables[0][3] = range;
		tileables[1][0] = base;
		tileables[1][1] = farm;
		tileables[2][0] = rally;
		tileables[3][0] = allArmy;
		tileables[3][1] = combatArmy;
		tileables[3][2] = supportArmy;
		
	}

	public int[][] getArrayOfSizes() {
		arrayOfSizes[0][0] = explorerSize;
		arrayOfSizes[0][1] = this.colonistSize;
		arrayOfSizes[0][2] = meleeSize;
		arrayOfSizes[0][3] = rangeSize;
		arrayOfSizes[1][0] = baseSize;
		arrayOfSizes[1][1] = farmSize;
		arrayOfSizes[2][0] = rallySize;
		arrayOfSizes[3][0] = allArmySize;
		arrayOfSizes[3][1] = combatArmySize;
		arrayOfSizes[3][2] = supportArmySize;
		return arrayOfSizes;
	}

	public void makeArmy(Tile t) {
		int tempID = -1;
		int i;
		if (this.rallySize < 10) {
			for (i = 0; i < maxID; i++) {
				if (!rallyID.check(i)) {
					tempID = i + 1;
					rallyID.set(i);
					break;
				}
			}
			rally[rallySize] = new Rally(tempID, this,m);
			rally[rallySize] = rally[rallySize];
			t.putTileable(rally[rallySize]);
			rally[rallySize].setDestX(t.getX());
			rally[rallySize].setDestY(t.getY());
		}
		rallySize++;
	}

	public void makeBase(Tile t) {
		int tempID = -1;
		int i;
		if (this.baseSize < 10) {
			for (i = 0; i < maxID; i++) {
				if (!structureID.check(i)) {
					tempID = i + 1;
					structureID.set(i);
					break;
				}
			}
			base[baseSize] = new Base(tempID, this);
			structure[structureSize] = base[baseSize];
			t.putTileable(base[baseSize]);
			base[baseSize].setDestX(t.getX());
			base[baseSize].setDestY(t.getY());
		}
		baseSize++;
		structureSize++;
		getArrayOfSizes();
	}

	public void makeFarm(Tile t) {
		int tempID = -1;
		int i;
		if (this.baseSize < 10) {
			for (i = 0; i < maxID; i++) {
				if (!structureID.check(i)) {
					tempID = i + 1;
					structureID.set(i);
					break;
				}
			}
			farm[farmSize] = new Farm(tempID, this);
			structure[structureSize] = farm[farmSize];
			t.putTileable(farm[farmSize]);
			farm[farmSize].setDestX(t.getX());
			farm[farmSize].setDestY(t.getY());
		}
		farmSize++;
		structureSize++;
		getArrayOfSizes();
	}

	public void makeExplorer(Tile t) {
		int tempID = -1;
		int i;
		if (this.explorerSize < 10 && this.unitSize < 25 && this.food > 20) {
			for (i = 0; i < maxID; i++) {
				if (!unitID.check(i)) {
					tempID = i + 1;
					unitID.set(i);
					break;
				}
			}

			explorer[explorerSize] = new Explorer(tempID, this);
			unit[unitSize] = explorer[explorerSize];
			t.putTileable(explorer[explorerSize]);
			explorer[explorerSize].setDestX(t.getX());
			explorer[explorerSize].setDestY(t.getY());
		}
		explorerSize++;
		unitSize++;
		getArrayOfSizes();
	}

	public void makeColonist(Tile t) {
		int tempID = -1;
		int i;
		if (this.colonistSize < 10 && this.unitSize < 25 && this.food > 20) {
			for (i = 0; i < maxID; i++) {
				if (!unitID.check(i)) {
					tempID = i + 1;
					unitID.set(i);
					break;
				}
			}
			colonist[colonistSize] = new Colonist(tempID, this);
			unit[unitSize] = colonist[colonistSize];
			t.putTileable(colonist[colonistSize]);
			colonist[colonistSize].setDestX(t.getX());
			colonist[colonistSize].setDestY(t.getY());
		}

		colonistSize++;
		unitSize++;
		getArrayOfSizes();
	}

	public void makeMelee(Tile t) {
		int tempID = -1;
		int i;
		if (this.meleeSize < 10 && this.unitSize < 25 && this.food > 20) {
			for (i = 0; i < maxID; i++) {
				if (!unitID.check(i)) {
					tempID = i + 1;
					unitID.set(i);
					break;
				}
			}
			melee[meleeSize] = new Melee(tempID, this);
			unit[unitSize] = melee[meleeSize];
			t.putTileable(melee[meleeSize]);
			melee[meleeSize].setDestX(t.getX());
			melee[meleeSize].setDestY(t.getY());
		}

		meleeSize++;
		unitSize++;
		getArrayOfSizes();
	}

	public void makeRange(Tile t) {
		int tempID = -1;
		int i;
		if (this.rangeSize < 10 && this.unitSize < 25 && this.food > 20) {
			for (i = 0; i < maxID; i++) {
				if (!unitID.check(i)) {
					tempID = i + 1;
					unitID.set(i);
					break;
				}
			}
			range[rangeSize] = new Range(tempID, this);
			unit[unitSize] = range[rangeSize];
			t.putTileable(range[rangeSize]);
			range[rangeSize].setDestX(t.getX());
			range[rangeSize].setDestY(t.getY());
		}

		rangeSize++;
		unitSize++;
		getArrayOfSizes();
	}

	public void destroyStructure(int _id) {

		int i;
		int p = -1;
		boolean found = false;
		for (i = 0; i < structureSize; i++) {
			if (structure[i].getStatus()[0] == _id) {

				found = true;
				break;
			}
		}
		if (found) {
			structureID.clr(i);

			p = this.structure[i].getType();
			this.structure[i] = null;
			structureSize--;
			for (int j = i; j < structureSize; j++) {
				structure[j] = structure[j + 1];
			}
			structure[structureSize] = null;

			switch (p) {
			case 10:// base
				for (i = 0; i < baseSize; i++) {

					if (base[i].getStatus()[0] == _id) {

						base[i] = null;
						baseSize--;

						for (int j = i; j < baseSize; j++) {
							base[j] = base[j + 1];
						}
						base[baseSize] = null;

						break;
					}
				}
				break;
			case 11:// farm
				for (i = 0; i < farmSize; i++) {
					if (farm[i].getStatus()[0] == _id) {
						farm[i] = null;
						farmSize--;

						for (int j = i; j < farmSize; j++) {
							farm[j] = farm[j + 1];
						}
						farm[farmSize] = null;
						break;
					}
				}
				break;

			default:
			}
		}
		getArrayOfSizes();
	}
	public Unit getUnit(int _id)
	{
			int i;
		int p = -1;
		boolean found = false;
		for (i = 0; i < unitSize; i++) {
			if (unit[i].getStatus()[0] == _id) {

				break;
			}
		}
		return unit[i];
		
	}
	
	public void incResource(int _type)
	{
		if(_type==70) this.gold+=10;
		else if(_type==71) this.lumber+=10;
	}
	public void destroyUnit(int _id) {
		
		int i;
		int p = -1;
		boolean found = false;
		for (i = 0; i < unitSize; i++) {
			if (unit[i].getStatus()[0] == _id) {

				found = true;
				break;
			}
		}
		if (found) {
			unitID.clr(i);

			p = this.unit[i].getType();
			this.unit[i] = null;
			unitSize--;
			for (int j = i; j < unitSize; j++) {
				unit[j] = unit[j + 1];
			}
			unit[unitSize] = null;

			switch (p) {
			case 0:
				for (i = 0; i < explorerSize; i++) {

					if (explorer[i].getStatus()[0] == _id) {

						explorer[i] = null;
						explorerSize--;

						for (int j = i; j < explorerSize; j++) {
							explorer[j] = explorer[j + 1];
						}
						explorer[explorerSize] = null;

						break;
					}
				}
				break;
			case 1:
				for (i = 0; i < this.colonistSize; i++) {
					if (colonist[i].getStatus()[0] == _id) {
						colonist[i] = null;
						this.colonistSize--;

						for (int j = i; j < this.colonistSize; j++) {
							colonist[j] = colonist[j + 1];
						}
						colonist[this.colonistSize] = null;
						break;
					}
				}
				break;
			case 2:
				for (i = 0; i < meleeSize; i++) {
					if (melee[i].getStatus()[0] == _id) {
						melee[i] = null;
						meleeSize--;
						break;
					}
				}
				break;
			case 3:
				for (i = 0; i < rangeSize; i++) {
					if (range[i].getStatus()[0] == _id) {
						range[i] = null;
						rangeSize--;
						break;
					}
				}
				break;
			default:
			}
		}
getArrayOfSizes();
	}

	public Tileable[][][] getTileables() {
		return tileables;
	}

	public int getGold() {
		return this.gold;
	}

	public void incGold(boolean cond) {
		if (cond)
			this.gold += 5;
	}

	public void decGold(boolean cond) {
		if (cond)
			this.gold -= 5;
	}

	public int getLumber() {
		return this.lumber;
	}

	public void incLumber(boolean cond) {
		if (cond)
			this.lumber += 5;
	}

	public void decLumber(boolean cond) {
		if (cond)
			this.lumber -= 5;
	}

	public int getFood() {
		return this.food;
	}

	public Base[] getBases() {
		return this.base;
	}

	public void incFood(boolean cond) {
		if (cond)
			this.food += 5;
	}

	public void decFood(boolean cond, int upkeep) {
		if (this.food < upkeep) {
			cond = false;
			this.food = 0;
		} else {
			if (cond)
				this.food -= upkeep;
		}
	}

	public void consumeFood(int upkeep) {
		food-=upkeep;
	}

	public int getStructureSize() {
		return structureSize;
	}

	public int getArmySize() {
		return rallySize;
	}

	public int getUnitSize() {
		return unitSize;
	}

	public int getID() {
		return this.playerID;
	}

	public String toString() {
		String s = "Player Information";
		s += "\nPlayer ID: " + this.playerID;
		s += "\nStructure size: " + this.structureSize;
		s += "\nUnit size: " + this.unitSize;
		s += "\nArmy size: " + this.rallySize;
		s += "\nGold: " + this.gold;
		s += "\nLumber: " + this.lumber;
		s += "\nFood: " + this.food;
		return s;
	}
}
